package myTest.proxy

import kotlin.properties.Delegates
import kotlin.reflect.KProperty

//////类委托////

interface Animal {

    val color: String

    fun printColor()

}

//创建委托类
class Dog : Animal {
    override val color: String
        get() = "黄色"

    override fun printColor() {
        println("the dog is $color")
    }

}

//1.将委托类作为构造器形参传入（常用）
class Dog1(dog: Animal) : Animal by dog


//2.新建委托类对象
class Dog2 : Animal by Dog()

//3.新建委托类，并自己实现方法/属性
class Dog3 : Animal by Dog() {

    override val color: String
        get() = "red"

    override fun printColor() {
        println("$color dog")
    }
}

//////类委托////


//////属性委托////

//语法格式：val/var <属性名>: <类型> by <表达式>

class FieldProxy {
    var name: String by ProxyTest01()

    val age: Int by ProxyTest02()
}

class ProxyTest01 {

    var nickName = "joke"

    operator fun getValue(fieldProxy: FieldProxy, property: KProperty<*>): String {
        println(
            "ProxyTest01-----getValue-----" +
//                "${fieldProxy.name}---${fieldProxy.age}" +
                    "--isFinal?--${property.isFinal}"
        )
        return nickName
    }

    operator fun setValue(fieldProxy: FieldProxy, property: KProperty<*>, value: String) {
        println(
            "ProxyTest01-----setValue----" +
//                "${fieldProxy.name}---${fieldProxy.age}" +
                    "--isFinal?--${property.isFinal}"
        )
        nickName = value
    }

}

class ProxyTest02 {
    var age = 18

    operator fun getValue(fieldProxy: FieldProxy, property: KProperty<*>): Int {
        println(
            "ProxyTest02-----getValue" +
//                "------${fieldProxy.name}---${fieldProxy.age}" +
                    "--isFinal?--${property.isFinal}"
        )
        return age
    }
}


//////属性委托////


//////标准委托////kotlin内置工厂方法实现的属性委托

//lazy 实现延迟属性的委托：第一次调用 get() 会执行已传递给 lazy() 的 lamda 表达式并记录结果， 后续调用 get() 只是返回记录的结果

val lazyField by lazy {
    println("only print once")
    "multiple invoke"
}

//Delegates.observable() 接受两个参数: 第一个是初始化值, 第二个是属性值变化事件的响应器(handler)。 在属性赋值后会执行事件的响应器(handler)，它有三个参数：被赋值的属性、旧值和新值

class ObservableProxy {
    var name: String by Delegates.observable("init") { field, old, new ->
        println("${field.name}----旧值:${old}------新值:${new}")
    }
}

//////标准委托////


fun main() {

    val dog = Dog()

    //1
    val dog1 = Dog1(dog)
    dog1.color
    dog1.printColor()

    //2
    val dog2 = Dog2()
    dog2.color
    dog2.printColor()

    //3
    val dog3 = Dog3()
    dog3.color
    dog3.printColor()


    //属性委托
    val fieldProxy = FieldProxy()

    println("main------${fieldProxy.name}------${fieldProxy.age}")

    fieldProxy.name = "mike"
    println("main------${fieldProxy.name}------${fieldProxy.age}")

    for (i in 0..3) {
        println(lazyField)
    }

    val observableProxy = ObservableProxy()
    observableProxy.name = "第一次赋值"
    observableProxy.name = "第二次赋值"

    //将属性存储在映射中，将map转bean实体
    val map: MutableMap<String, Any?> = mutableMapOf(
        "name" to "hello",
        "age" to 20
    )

    val bean01 = Bean01(map)
    println("output bean01 : name is ${bean01.name},age is ${bean01.age}")
}

class Bean01(map: MutableMap<String, Any?>) {
    val name: String by map
    val age: Int by map
}




